const express = require('express');
const multer = require('multer');
const cors = require('cors');
const path = require('path');
const fs = require('fs');
const os = require('os'); // 引入 os 模块

const app = express();

// 在文件顶部添加以下代码
const isPackaged = typeof process.pkg !== 'undefined';
const baseDir = isPackaged ? path.dirname(process.execPath) : __dirname;

// 确保 uploads 目录存在
const uploadDir = path.join(baseDir, 'uploads');
if (!fs.existsSync(uploadDir)) {
    fs.mkdirSync(uploadDir);
}

// 定义各个文件夹及其对应的文件类型
const fileCategories = {
    audio: ['m4a', 'mp3', 'wav', 'ogg', 'aac', 'flac'], // 音频文件
    documents: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'rtf', 'odt', 'ods', 'odp'], // 文档文件
    images: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp'], // 图片文件
    videos: ['mp4', 'mov', 'avi', 'mkv', 'flv', 'wmv', 'webm'], // 视频文件
    archives: ['zip', 'rar', '7z', 'tar', 'gz', 'bz2'], // 压缩文件
    data: ['csv', 'json', 'xml', 'sql', 'db', 'sqlite'], // 数据文件
    code: ['js', 'html', 'css', 'py', 'java', 'cpp', 'c', 'h', 'php', 'rb', 'swift', 'go', 'rs', 'ts', 'json'], // 代码文件
    executables: ['exe', 'dmg', 'msi', 'deb', 'rpm'], // 可执行文件
    others: [] // 其他文件
};

// 创建对应的文件夹
for (const category in fileCategories) {
    const categoryPath = path.join(uploadDir, category);
    if (!fs.existsSync(categoryPath)) {
        fs.mkdirSync(categoryPath);
    }
}

// 确保 downloads 目录存在
const downloadDir = path.join(baseDir, 'downloads');
if (!fs.existsSync(downloadDir)) {
    fs.mkdirSync(downloadDir);
}

// 也创建 downloads 的对应分类文件夹
for (const category in fileCategories) {
    const categoryPath = path.join(downloadDir, category);
    if (!fs.existsSync(categoryPath)) {
        fs.mkdirSync(categoryPath);
    }
}

app.use(cors());
app.use(express.static(baseDir));

// 配置Multer
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        // 获取文件扩展名（不包含.）
        const ext = path.extname(file.originalname).toLowerCase().substring(1);

        // 根据文件扩展名确定存储路径
        let dest;
        for (const category in fileCategories) {
            if (fileCategories[category].includes(ext)) {
                dest = path.join(uploadDir, category);
                break;
            }
        }

        // 如果没有匹配的类别，使用 'others' 文件夹
        if (!dest) {
            dest = path.join(uploadDir, 'others');
        }

        cb(null, dest);
    },
    filename: function (req, file, cb) {
         // 使用Buffer.from结合latin1和utf8编码转换来处理文件名乱码问题
         let fileName = file.originalname;
         try {
             // 解码文件名
             fileName = Buffer.from(file.originalname, 'latin1').toString('utf8');
         } catch (err) {
             console.error('解码文件名失败:', err);
         }
         // 确保文件名不包含路径信息
         fileName = path.basename(fileName);
         // 使用时间戳和解码后的文件名，避免重复
         cb(null, Date.now() + '-' + fileName);
    }
});

const upload = multer({
    storage: storage,
}).array('file');

// 上传文件接口
app.post('/upload', (req, res) => {
    console.log('Upload request received');
    upload(req, res, function (err) {
        if (err) {
            console.error('Upload error:', err);
            res.status(500).send('Upload failed');
        } else {
            // 过滤掉系统生成的特殊文件
            req.files = req.files.filter(file => {
                return !file.originalname.startsWith('.') && 
                       file.originalname !== 'Thumbs.db' && 
                       file.originalname !== 'desktop.ini';
            });
            console.log('Files uploaded:', req.files);
            res.send('Files uploaded successfully');
        }
    });
});

// 获取downloads文件夹中的所有文件
app.get('/get-file-list', (req, res) => {
    const source = req.query.source || 'downloads'; // 默认为 'downloads'
    const baseDir = source === 'downloads' ? downloadDir : uploadDir;
    const files = [];
    for (const category in fileCategories) {
        const categoryPath = path.join(baseDir, category);
        if (fs.existsSync(categoryPath)) {
            const categoryFiles = fs.readdirSync(categoryPath).filter(file => {
                return !file.startsWith('.') && 
                       file !== 'Thumbs.db' && 
                       file !== 'desktop.ini';
            }).map(file => {
                // 添加文件大小信息
                const filePath = path.join(categoryPath, file);
                const stat = fs.statSync(filePath);
                return {
                    name: file,
                    category: category,
                    path: path.join(category, file),
                    size: stat.size  // 添加文件大小属性
                };
            });
            files.push(...categoryFiles);
        }
    }
    console.log('File list:', files);
    res.json(files);
});

// 下载单个文件
app.get('/download-file', (req, res) => {
    const fileName = req.query.name;
    const category = req.query.category;
    const source = req.query.source || 'downloads';
    const baseDir = source === 'downloads' ? downloadDir : uploadDir;

    if (!category || !fileName) {
        return res.status(400).send('Missing category or file name');
    }

    const filePath = path.join(baseDir, category, fileName);
    
    if (!fs.existsSync(filePath)) {
        return res.status(404).send('文件未找到');
    }

    const stat = fs.statSync(filePath);
    const fileSize = stat.size;
    const range = req.headers.range;

    // 支持断点续传
    if (range) {
        const parts = range.replace(/bytes=/, "").split("-");
        const start = parseInt(parts[0], 10);
        const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;
        const chunkSize = (end - start) + 1;
        
        if (start >= fileSize || end >= fileSize) {
            res.status(416).send('请求范围不符合要求');
            return;
        }

        const fileStream = fs.createReadStream(filePath, { 
            start, 
            end,
            highWaterMark: 16 * 1024 * 1024 // 16MB缓冲区
        });
        
        fileStream.on('error', (err) => {
            console.error('文件流错误:', err);
            if (!res.headersSent) {
                res.status(500).send('文件传输中断');
            }
        });

        const head = {
            'Content-Range': `bytes ${start}-${end}/${fileSize}`,
            'Accept-Ranges': 'bytes',
            'Content-Length': chunkSize,
            'Content-Type': 'application/octet-stream',
        };

        res.writeHead(206, head);
        fileStream.pipe(res);
    } else {
        // 普通下载
        const head = {
            'Content-Length': fileSize,
            'Content-Type': 'application/octet-stream',
        };
        res.writeHead(200, head);
        
        const fileStream = fs.createReadStream(filePath, { 
            highWaterMark: 16 * 1024 * 1024 // 16MB缓冲区
        });
        
        fileStream.on('error', (err) => {
            console.error('文件流错误:', err);
            if (!res.headersSent) {
                res.status(500).send('文件传输中断');
            }
        });
        
        fileStream.pipe(res);
    }
});

// 完整文件下载接口
app.get('/download-full', (req, res) => {
    const { name, category, source } = req.query;
    const baseDir = source === 'downloads' ? downloadDir : uploadDir;
    const filePath = path.join(baseDir, category, name);
    
    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
        return res.status(404).send('文件未找到');
    }
    
    try {
        // 获取文件信息
        const stat = fs.statSync(filePath);
        const fileSize = stat.size;
        
        // 设置下载头
        res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(name)}"`);
        res.setHeader('Content-Type', 'application/octet-stream');
        res.setHeader('Content-Length', fileSize);
        
        // 流式传输文件
        const fileStream = fs.createReadStream(filePath, { highWaterMark: 64 * 1024 }); // 64KB缓冲区
        fileStream.pipe(res);
        
        fileStream.on('error', (err) => {
            console.error('文件流错误:', err);
            if (!res.headersSent) {
                res.status(500).send('文件传输中断');
            }
        });
        
    } catch (error) {
        console.error('下载文件失败:', error);
        res.status(500).send('服务器处理文件时出错');
    }
});

// 添加文件信息接口
app.get('/file-info', (req, res) => {
    const fileName = req.query.name;
    const category = req.query.category;
    const source = req.query.source || 'downloads';
    const baseDir = source === 'downloads' ? downloadDir : uploadDir;

    if (!category || !fileName) {
        return res.status(400).send('Missing category or file name');
    }

    const filePath = path.join(baseDir, category, fileName);
    
    if (!fs.existsSync(filePath)) {
        return res.status(404).send('文件未找到');
    }

    try {
        const stat = fs.statSync(filePath);
        res.json({
            size: stat.size,
            chunkSize: 1024 * 1024 * 100 // 推荐分片大小 (100MB)
        });
    } catch (err) {
        console.error('获取文件信息失败:', err);
        res.status(500).send('获取文件信息失败');
    }
});

// 获取本机IP地址
function getLocalIP() {
    const interfaces = os.networkInterfaces();
    for (const name of Object.keys(interfaces)) {
        for (const interface of interfaces[name]) {
            if (interface.family === 'IPv4' && !interface.internal) {
                return interface.address;
            }
        }
    }
    return 'localhost'; // 默认回退到 localhost
}

app.listen(3000, '0.0.0.0', () => {
    const ip = getLocalIP();
    console.log(`Server started at http://${ip}:3000`);
    console.log(`Access the web interface at http://${ip}:3000/index.html`);
});